郭天祥的10天学会51单片机 | 您所在的位置:网站首页 › 窗帘 软装 › 郭天祥的10天学会51单片机 |
要多练,多练C语言程序,练习C语言程序编程思路,可以把别人的程序改改,找些电路焊接调试 AD985可以产生方波,三角波,正弦波 低通滤波器是通过低频阻止高频,作用是滤除杂波 液晶显示单片机状态 运算放大器放大波形 积分器将方波积分成三角波 AD985里面有比较器可以将正弦波变成方波 AD985是5伏的,单片机是3伏的,两者之间要有个电压转换器 数码管不仅可以用锁存器来驱动,也可以用三极管来驱动 一个函数用来刷新秒,分,时 键盘调节用三个键:功能键(秒的光标在闪烁,此时可以调节时间,分和小时同理),功能键第一次按键调节秒,第二次调节分,第三次调节小时,第四次恢复(程序中可以用一个变量计数,这个变量是几就执行相应的程序);TX-1C型单片机实验板原理图中因为LCDEN和RS用了,就不用它们做键盘了,可以用S9,S13,S17,使用时将RD置0,只需检测P3.0,P3.1和CSDA,键盘上最右列的三个,检测这三个键哪个键为低电平,就能知道哪个键被按下,这里把矩阵键盘(P3.0,P3.1和CSDA)当独立键盘使用 编程时,先让液晶显示,再利用定时器定时显示时间,先显示秒,再显示分和十,再做键盘调节,先做一个键调节,然后做其它键调节 #include #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; sbit wela=P2^7; sbit rs=P3^5; sbit lcden=P3^4; sbit s1=P3^0;//键盘的三个功能键 sbit s2=P3^1; sbit s3=P3^2;//对应于CSDA sbit rd=P3^7;//将RD置0,检测P3.0,P3.1和CSDA的状态是否为低电平 uchar count,s1num; char miao,shi,fen; uchar code table[]=" 2007-7-30 MON";//加上空格为向右移动再显示 uchar code table1[]=" 00:00:00"; void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void write_com(uchar com) { rs=0; lcden=0; P0=com; delay(5); lcden=1; delay(5); lcden=0; } void write_date(uchar date) { rs=1; lcden=0; P0=date; delay(5); lcden=1; delay(5); lcden=0; } void init() { uchar num; dula=0;//开始要关断数码管 wela=0; lcden=0; // fen=59; // miao=53; // shi=23; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80); for(num=0;num write_date(table1[num]); delay(5); } TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; } void write_sfm(uchar add,uchar date)//写时或分或秒(2位数),add 是位置,date是数值 { uchar shi,ge; shi=date/10;//因为数码管一位一位显示,时,分,秒都是两位数,要分开 ge=date%10; write_com(0x80+0x40+add); write_date(0x30+shi);//见字符手册的PDF的P11,例如6是30+6 write_date(0x30+ge); } void keyscan() { rd=0; if(s1==0) { delay(5);//消抖 if(s1==0)//第一个功能键的作用,让秒钟停止闪烁 { s1num++; while(!s1);//键盘松手才开始执行功能键的下列程序 if(s1num==1) { TR0=0; write_com(0x80+0x40+10);//光标的地址,因为写一下光标就跳到后一位,为了让光标在秒那要重写下光标的地址 write_com(0x0f);//光标闪烁 } } if(s1num==2)//第一个功能键的第二次按下,改变分 { write_com(0x80+0x40+7); } if(s1num==3)//第一个功能键的第三次按下,改变小时 { write_com(0x80+0x40+4); } if(s1num==4)//光标不再闪烁,计数器继续工作 { s1num=0; write_com(0x0c); TR0=1; } } if(s1num!=0)//第一个键按下之后,第二个和第三个键才好使,如果把对第二个和第三个键进行控制的程序放在第一个if(s1==0)语句里面,只有当第一个键按下的瞬间第二个或第三个键也被按下,才能执行第二个或第三个键的程序,所以应该在第一个if(s1==0)语句并列的位置写程序对第二个和第三个键进行控制 { if(s2==0) { delay(5); if(s2==0) { while(!s2);//等待松手,如果不等待松手单片机就会在键盘按下的时 间里程序执行很多次 if(s1num==1)//当s1num==1,表示第一个键秒钟闪烁,即另两个键的按下可以用s1num的值来判断 { miao++; if(miao==60) miao=0; write_sfm(10,miao);//改变秒的数值后显示,第一个参数不能写成0x10,写成0x10就会出错 write_com(0x80+0x40+10);//光标指到秒的位置,从左往右数,数到秒的十位处 } if(s1num==2) { fen++; if(fen==60) fen=0; write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3) { shi++; if(shi==24) shi=0; write_sfm(4,shi); write_com(0x80+0x40+4); } } } if(s3==0) { delay(5); if(s3==0) { while(!s3); if(s1num==1) { /* if(miao==0) { miao=59; write_sfm(10,miao); write_com(0x80+0x40+10); }*/ miao--; if(miao==-1) miao=59; write_sfm(10,miao); write_com(0x80+0x40+10); } if(s1num==2) { fen--; if(fen==-1) fen=59; write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3) { shi--; if(shi==-1) shi=23; write_sfm(4,shi); write_com(0x80+0x40+4); } } } } } void main() { init(); while(1) { keyscan(); } // while(1); } void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; count++; if(count==18)//因为是12MHZ,所以不是count=20(对应11.0592MHZ) { count=0; miao++; if(miao==60) { miao=0; fen++; if(fen==60) { fen=0; shi++; if(shi==24) { shi=0; } write_sfm(4,shi); } write_sfm(7,fen); } write_sfm(10,miao);//到一秒只要秒不到60秒进位就改变显示,因为 table1[]=" 00:00:00"; //对于秒的位置是十,即前面空了十个空格,所以第一个参数是10,该句和第一个if是并列的关系 } } 星期可以用switch case语句 我的程序: #include #define uint unsigned int #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; sbit rs=P3^5; sbit lcden=P3^4; sbit rd=P3^7; sbit s1=P3^1; sbit s2=P3^2; sbit s3=P3^3; uchar code table[]=" 2012-12-31 MON"; uchar code table1[]=" 23:59:50"; uchar code table2[]="MONTUEWEDTHRFRISATSUN"; uchar count,s1num,flag; char shi,fen,miao,xq,day,month; int year; void delay(uint z) { uchar x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void write_com(uchar com) { rs=0; lcden=0; P0=com; delay(5); lcden=1; delay(5); lcden=0; } void write_date(uchar date) { rs=1; lcden=0; P0=date; delay(5); lcden=1; delay(5); lcden=0; } void init() { uchar num; shi=23; fen=59; miao=50; xq=0; day=31; month=12; year=2012; dula=0; wela=0; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80); for(num=0;num uchar kk; write_com(0x80+12);//星期的位置是从左数第十二位 for(kk=0;kk uchar num; date++; if(date==7) date=0; switch(date) { case 0:num=0; break; case 1:num=3; break; case 2:num=6; break; case 3:num=9; break; case 4:num=12; break; case 5:num=15; break; case 6:num=18; break; } displayxq(num); } void write_y(uchar add,int date)//这里date是2012,要用合适的类型定义 { uchar qian,bai,shi,ge; qian=date/1000; bai=date%1000/100; shi=date%100/10; ge=date%10; write_com(0x80+add); write_date(0x30+qian); write_date(0x30+bai); write_date(0x30+shi); write_date(0x30+ge); } void write_md(uchar add,uchar date) { uchar shi,ge; shi=date/10; ge=date%10; write_com(0x80+add); write_date(0x30+shi); write_date(0x30+ge); } void write_rq(char date) { date++; if((year%4==0 && year%100!=0) || year%400==0) flag=1; if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10) { if(date==32) { date=1; } month++; } if(month==2) { if(flag==1) { if(date==30) { date=1; } } if(flag==0) { if(date==29) { date=1; } } flag=0; month++; } if(month==4 || month==6 || month==9 || month==11 ) { if(date==31) { date=1; } month++; } if(month==12) { if(date==32) { date=1; month=1; } year++; if(year==10000) year=0; } write_md(9,date); write_md(6,month); write_y(1,year); } void keyscan() { uchar num; rd=0; if(s1==0) { delay(5); if(s1==0) { s1num++; while(!s1); if(s1num==1) { TR0=0; write_com(0x80+0x40+10); write_com(0x0f); } if(s1num==2) { write_com(0x80+0x40+7); } if(s1num==3) { write_com(0x80+0x40+4); } if(s1num==4) { write_com(0x80+12); } if(s1num==5) { write_com(0x80+9); } if(s1num==6) { write_com(0x80+6); } if(s1num==7) { write_com(0x80+1); } if(s1num==8) { s1num=0; write_com(0x0c); TR0=1; } } } if(s1num!=0) { if(s2==0) { delay(5); if(s2==0) { while(!s2); if(s1num==1) { miao++; if(miao==60) miao=0; write_sfm(10,miao); write_com(0x80+0x40+10); } if(s1num==2) { fen++; if(fen==60) fen=0; write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3) { shi++; if(shi==24) shi=0; write_sfm(4,shi); write_com(0x80+0x40+4); } if(s1num==4) { xq++; if(xq==7) xq=0; switch(xq) { case 0:num=0; break; case 1:num=3; break; case 2:num=6; break; case 3:num=9; break; case 4:num=12; break; case 5:num=15; break; case 6:num=18; break; } displayxq(num); write_com(0x80+12); } if(s1num==5) { day++; if((year%4==0 && year%100!=0) || year%400==0) flag=1; if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10) { if(day==32) { day=1; } } if(month==2) { if(flag==1) { if(day==30) { day=1; } } if(flag==0) { if(day==29) { day=1; } } flag=0; } if(month==4 || month==6 || month==9 || month==11 ) { if(day==31) { day=1; } } if(month==12) { if(day==32) { day=1; } } write_md(9,day); write_com(0x80+9); } if(s1num==6) { month++; if(month==13) month=1; write_md(6,month); write_com(0x80+6); } if(s1num==7) { year++; if(year==10000) year=0; write_y(1,year); write_com(0x80+1); } } } if(s3==0) { delay(5); if(s3==0) { while(!s3); if(s1num==1) { miao--; if(miao==-1) miao=59; write_sfm(10,miao); write_com(0x80+0x40+10); } if(s1num==2) { fen--; if(fen==-1) fen=59; write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3) { shi--; if(shi==-1) shi=23; write_sfm(4,shi); write_com(0x80+0x40+4); } if(s1num==4) { xq--; if(xq==-1) xq=6; switch(xq) { case 0:num=0; break; case 1:num=3; break; case 2:num=6; break; case 3:num=9; break; case 4:num=12; break; case 5:num=15; break; case 6:num=18; break; } displayxq(num); write_com(0x80+12); } if(s1num==5) { day--; if((year%4==0 && year%100!=0) || year%400==0) flag=1; if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10) { if(day==0) { day=31; } } if(month==2) { if(flag==1) { if(day==0) { day=29; } } if(flag==0) { if(day==0) { day=28; } } flag=0; } if(month==4 || month==6 || month==9 || month==11 ) { if(day==0) { day=30; } } if(month==12) { if(day==0) { day=31; } } write_md(9,day); write_com(0x80+9); } if(s1num==6) { month--; if(month==0) month=12; write_md(6,month); write_com(0x80+6); } if(s1num==7) { year--; if(year==0) year=9999; write_y(1,year); write_com(0x80+1); } } } } } void main() { init(); while(1) { keyscan(); } } void timer0() interrupt 1 { TH0=(65535-50000)/256; TL0=(65535-50000)%256; count++; if(count==20) { count=0; miao++; if(miao==60) { miao=0; fen++; if(fen==60) { fen=0; shi++; if(shi==24) { shi=0; } write_sfm(4,shi); write_xq(xq);//星期++的判断和显示都放到子函数里,和放到此中断函数 里效果相同 write_rq(day);//日期++的判断和显示都放到子函数里,和放到此中断函数里效果相同 } write_sfm(7,fen); } write_sfm(10,miao); } } |
CopyRight 2018-2019 实验室设备网 版权所有 |